/*
 * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <hi_task.h>
#include <string.h>
#include <hi_wifi_api.h>
#include <hi_mux.h>
#include <hi_io.h>
#include <hi_gpio.h>
#include "iot_config.h"
#include "iot_log_tank.h"
#include "iot_main_tank.h"
#include "iot_profile_tank.h"
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "app_demo_uart_tank.h"
#include "app_demo_iot.h"
#include "tank_control.h"

/* attribute initiative to report */
#define TAKE_THE_INITIATIVE_TO_REPORT
#define ONE_SECOND                          (1000)
/* oc request id */
#define CN_COMMADN_INDEX                    "commands/request_id="
#define WECHAT_SUBSCRIBE_LIGHT              "light"
#define WECHAT_SUBSCRIBE_LIGHT_ON_STATE     "1"
#define WECHAT_SUBSCRIBE_LIGHT_OFF_STATE    "0"

int g_ligthStatus = -1;
typedef void (*FnMsgCallBack)(hi_gpio_value val);

typedef struct FunctionCallback {
    hi_bool  stop;
    hi_u32 conLost;
    hi_u32 queueID;
    hi_u32 iotTaskID;
    FnMsgCallBack    msgCallBack;
}FunctionCallback;
FunctionCallback g_functinoCallback;

/* CPU Sleep time Set */
unsigned int tankTaskMsleep(unsigned int ms)
{
    if (ms <= 0) {
        return HI_ERR_FAILURE;
    }
    return hi_sleep((hi_u32)ms);
}

//根据云端发出的消息控制板端
static void DeviceConfigInit(hi_gpio_value val)
{
    //灯
    hi_io_set_func(HI_IO_NAME_GPIO_9, HI_IO_FUNC_GPIO_9_GPIO);
    hi_gpio_set_dir(HI_GPIO_IDX_9, HI_GPIO_DIR_OUT); //输出方向1
    hi_gpio_set_ouput_val(HI_GPIO_IDX_9, val); //val:0,1高低电频 

    // hi_io_set_func(HI_IO_NAME_GPIO_10, HI_IO_FUNC_GPIO_10_GPIO);
    // hi_gpio_set_dir(HI_GPIO_IDX_10, HI_GPIO_DIR_OUT); //输出方向1
    // hi_gpio_set_ouput_val(HI_GPIO_IDX_10, val); //val:0,1高低电频 
}

static int  DeviceMsgCallback(FnMsgCallBack msgCallBack)
{
    g_functinoCallback.msgCallBack = msgCallBack;
    return 0;
}

static void wechatControlDeviceMsg(hi_gpio_value val)
{
    DeviceConfigInit(val);
}

// < this is the callback function, set to the mqtt, and if any messages come, it will be called
// < The payload here is the json string
static void DemoMsgRcvCallBack(int qos, const char *topic, const char *payload)
{
    IOT_LOG_DEBUG("RCVMSG:QOS:%d TOPIC:%s PAYLOAD:%s\r\n", qos, topic, payload);
    /* 云端下发命令后，板端的操作处理 */
    if (strstr(payload, WECHAT_SUBSCRIBE_LIGHT) != NULL) {
        if (strstr(payload, WECHAT_SUBSCRIBE_LIGHT_OFF_STATE) != NULL) {
            wechatControlDeviceMsg(HI_GPIO_VALUE1);//云端给出高电频的信号1 关灯
            g_ligthStatus = HI_FALSE;
        } else {
            wechatControlDeviceMsg(HI_GPIO_VALUE0);//云端给出低电频的信号0 开灯
            g_ligthStatus = HI_TRUE;
        }
    }
    return HI_NULL;
}

/* publish sample */

// hi_void IotPublishSample(void)
// {
//     /* reported attribute */
//     //已经发布了的属性
//     WeChatProfile weChatProfile = {
//         .subscribeType = "type",
//         .status.subState = "state",
//         .status.subReport = "reported",
//         .status.reportVersion = "version",
//         .status.Token = "clientToken",
//         /* report motor */
//         .reportAction.subDeviceActionMotor = "motor",
//         .reportAction.motorActionStatus = 0, /* 0 : motor off */
//         /* report temperature */
//         .reportAction.subDeviceActionTemperature = "temperature",
//         .reportAction.temperatureData = 30, /* 30 :temperature data */
//         /* report humidity */
//         .reportAction.subDeviceActionHumidity = "humidity",
//         .reportAction.humidityActionData = 70, /* humidity data */
//         /* report light_intensity */
//         .reportAction.subDeviceActionLightIntensity = "light_intensity",
//         .reportAction.lightIntensityActionData = 60, /* 60 : light_intensity */
//     };

//     /* report light */
//     //可发布的属性(譬如控制灯亮进行射击)
//     if (g_ligthStatus == HI_TRUE) {
//         weChatProfile.reportAction.subDeviceActionLight = "light";
//         weChatProfile.reportAction.lightActionStatus = 1; /* 1: light on */
//     } else if (g_ligthStatus == HI_FALSE) {
//         weChatProfile.reportAction.subDeviceActionLight = "light";
//         weChatProfile.reportAction.lightActionStatus = 0; /* 0: light off */
//     } else {
//         weChatProfile.reportAction.subDeviceActionLight = "light";
//         weChatProfile.reportAction.lightActionStatus = 0; /* 0: light off */
//     }
//     /* profile report */
//     tankIoTProfilePropertyReport(CONFIG_USER_ID, &weChatProfile);
// }


/* custome publish Tank sample */
hi_void IotPublishTankSample(void)
{
    int tankmotorActionStatus;
    int tanktemperatureData;
    int tankhumidityActionData;
    int tanklightIntensityActionData;
    // custome
    int tankdetetActionStatus; // tank的状态
    printf("=========tankflag==========%d \n",tankflag);
    // printf("=========tankflagSize========%d \n",sizeof(tankflag));
    if (tankflag == 1) //
    {
        tankmotorActionStatus = x_min;
        tanktemperatureData = y_min;
        tankhumidityActionData = x_max;
        tanklightIntensityActionData = y_max;
        // custome
        tankdetetActionStatus = tankflag;//目标识别成功
    }else{
        tankmotorActionStatus = 0;
        tanktemperatureData = 0;
        tankhumidityActionData = 0;
        tanklightIntensityActionData = 0;
        // custome
        tankdetetActionStatus = 0;//待目标进入到检测视野中
    }
    /* reported attribute */
    //已经发布了的属性 
    WeChatTankProfile tankweChatProfile = {
        .tanksubscribeType = "type",
        .tankstatus.tanksubState = "state",
        .tankstatus.tanksubReport = "reported",
        .tankstatus.tankreportVersion = "version",
        .tankstatus.tankToken = "clientToken",
        /* report motor */ //电机
        .tankreportAction.tanksubDeviceActionMotor = "x_min",
        .tankreportAction.tankmotorActionStatus = tankmotorActionStatus, /* 0 : motor off */
        /* report temperature */ //温度
        .tankreportAction.tanksubDeviceActionTemperature = "y_min",
        .tankreportAction.tanktemperatureData = tanktemperatureData, /* 30 :temperature data */
        /* report humidity */ //湿度
        .tankreportAction.tanksubDeviceActionHumidity = "x_max",
        .tankreportAction.tankhumidityActionData = tankhumidityActionData, /* humidity data */
        /* report light_intensity */ //光照强度
        .tankreportAction.tanksubDeviceActionLightIntensity = "y_max",
        .tankreportAction.tanklightIntensityActionData = tanklightIntensityActionData, /* 60 : light_intensity */

        //================================custome======================
         /* report Tank status */ //坦克检测
        .tankreportAction.tanksubDeviceAction = "tank_detect",
        .tankreportAction.tankdetectStatus = tankdetetActionStatus, /* tank_detect */
    };

    /* report light */
    //可发布的属性 是否开灯 g_ligthStatus初始值为-1
    if (g_ligthStatus == HI_TRUE) {
        tankweChatProfile.tankreportAction.tanksubDeviceActionLight = "light";
        tankweChatProfile.tankreportAction.tanklightActionStatus = 1; /* 1: light on */
    } else if (g_ligthStatus == HI_FALSE) {
        tankweChatProfile.tankreportAction.tanksubDeviceActionLight = "light";
        tankweChatProfile.tankreportAction.tanklightActionStatus = 0; /* 0: light off */
    } else {
        tankweChatProfile.tankreportAction.tanksubDeviceActionLight = "light";
        tankweChatProfile.tankreportAction.tanklightActionStatus = 0; /* 0: light off */
    }
    /* profile report */ //发布
    tankIoTProfilePropertyReport(CONFIG_USER_ID, &tankweChatProfile);
}

// < this is the demo main task entry,here we will set the wifi/cjson/mqtt ready and
// < wait if any work to do in the while
int timeflag;//定义一个时间变量 来使3861有足够多的时间与云端进行连接
static hi_void *DemoEntry(const char *arg)
{
    tankWifiStaReadyWait();
    tankcJsonInit();
    tankIoTMain();
    /* 云端下发回调 */
    tankIoTSetMsgCallback(DemoMsgRcvCallBack);
    while (1) {
    /* 用户可以在这调用发布函数进行发布，需要用户自己写调用函数 */
    // IotPublishSample(); // 发布例程
        if(timeflag < 10) {
            /* 主动上报 */
            timeflag++;
            #ifdef TAKE_THE_INITIATIVE_TO_REPORT
                IotPublishTankSample(); // custome
            #endif
                tankTaskMsleep(4*ONE_SECOND);
        }else{
            #ifdef TAKE_THE_INITIATIVE_TO_REPORT
                IotPublishTankSample(); // custome
            #endif
                tankTaskMsleep(20);
            }
        printf("timeflag=%d \n",timeflag);
        //==========custome RobotTankTestTask======================
        printf("RobotTankTask waiting.....  sssss\r\n");
        //switch_init(); 
        //interrupt_monitor(); 
        //interrupt_monitor_laser();
        // unsigned int time = 20;
        //Oled_Task();
        if (timeflag == 10){
            printf("RobotTankTestTask ready go.....  sssss\r\n");
            switch (g_tank_status) {   //坦克状态判断
                case TANK_RECONNOITRE_STATUS:   //坦克侦察
                    g_tank_status = tank_reconnoitre();
                    break;
                case TANK_STOP_SHOOT_STATUS:  //坦克停止侦察并射击
                    tank_mode_control();
                    break;
                default:
                    break;
            }
            tankTaskMsleep(20);
        }
        IoTWatchDogDisable();
    }
    return NULL;
}

// < This is the demo entry, we create a task here,
// and all the works has been done in the demo_entry
#define CN_IOT_TASK_STACKSIZE  0x1000
#define CN_IOT_TASK_PRIOR 25
#define CN_IOT_TASK_NAME "IOTDEMO"

static void AppDemoIot(void)
{
    osThreadAttr_t attr;
    IoTWatchDogDisable();

    attr.name = "IOTDEMO";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = CN_IOT_TASK_STACKSIZE;
    attr.priority = CN_IOT_TASK_PRIOR;

    if (osThreadNew((osThreadFunc_t)DemoEntry, NULL, &attr) == NULL) {
        printf("[mqtt] Falied to create IOTDEMO!\n");
    }
}

SYS_RUN(AppDemoIot);